#ifndef RAFT_CORE_PERSISTER_H
#define RAFT_CORE_PERSISTER_H

#include <fstream>
#include <mutex>

namespace raftCore
{
/**
 * @brief Raft协议中的持久化管理器
 * 
 * 负责Raft节点关键状态（raftstate）和快照（snapshot）的持久化存储与读取，
 * 确保节点在重启后能恢复必要的状态数据。提供线程安全的操作接口，
 * 通过文件系统持久化数据，并在内存中维护缓存以提高访问效率。
 */
class Persister {
public:
    /**
     * @brief 保存Raft状态和快照数据
     * @param raftstate 待持久化的Raft核心状态数据（如当前任期、投票信息等）
     * @param snapshot 待持久化的快照数据（用于日志压缩后的状态恢复）
     * @note 同时更新内存缓存和持久化文件，确保数据一致性
     */
    void Save(std::string raftstate, std::string snapshot);

    /**
     * @brief 读取当前持久化的快照数据
     * @return 存储的快照数据（字符串形式）
     * @note 从内存缓存读取，避免频繁文件IO
     */
    std::string ReadSnapshot();

    /**
     * @brief 单独保存Raft状态数据
     * @param data 待保存的Raft状态数据
     * @note 用于仅更新Raft状态（如任期变化、投票结果）时调用
     */
    void SaveRaftState(const std::string& data);

    /**
     * @brief 获取当前Raft状态数据的大小
     * @return Raft状态数据的字节数
     * @note 基于内存缓存的m_raftStateSize，避免每次通过文件读取计算
     */
    long long RaftStateSize();

    /**
     * @brief 读取当前持久化的Raft状态数据
     * @return 存储的Raft状态数据（字符串形式）
     * @note 从内存缓存读取，提高访问效率
     */
    std::string ReadRaftState();

    /**
     * @brief 构造函数
     * @param me 节点ID，用于生成唯一的持久化文件名（避免多节点文件冲突）
     * @note 初始化文件路径、文件流和内存缓存，基于节点ID区分不同节点的持久化文件
     */
    explicit Persister(int me);

    /**
     * @brief 析构函数
     * @note 负责关闭文件流，释放相关资源
     */
    ~Persister();

private:
    /**
     * @brief 清除Raft状态数据
     * @note 同时清空内存缓存和对应的持久化文件
     */
    void clearRaftState();

    /**
     * @brief 清除快照数据
     * @note 同时清空内存缓存和对应的持久化文件
     */
    void clearSnapshot();

    /**
     * @brief 同时清除Raft状态和快照数据
     * @note 整合clearRaftState和clearSnapshot的功能
     */
    void clearRaftStateAndSnapshot();

    /**
     * @brief 文件流恢复函数（当流异常时尝试重新打开）
     */
    void recoverFileStreams();

private:
    std::mutex m_mutex;         // 互斥锁，保证多线程环境下对持久化数据操作的线程安全
    std::string m_raft_state;   // 内存缓存的Raft状态数据，减少文件IO次数
    std::string m_snapshot;     // 内存缓存的快照数据，减少文件IO次数
    
    /**
     * m_raftStateFileName: Raft状态数据的持久化文件名
     * @note 基于节点ID生成，确保单节点内唯一，如"raftstate_1.dat"（1为节点ID）
     */
    const std::string m_raft_state_file_name;

    /**
     * m_snapshotFileName: 快照数据的持久化文件名
     * @note 基于节点ID生成，确保单节点内唯一，如"snapshot_1.dat"（1为节点ID）
     */
    const std::string m_snapshot_file_name;

    /**
     * 保存raftState的输出流
     * @note 用于将Raft状态数据写入对应的持久化文件
     */
    std::ofstream m_raft_state_out_stream;

    /**
     * 保存snapshot的输出流
     * @note 用于将快照数据写入对应的持久化文件
     */
    std::ofstream m_snapshot_out_stream;

    /**
     * 缓存的raftState数据大小（字节数）
     * @note 避免每次通过读取文件或计算字符串长度获取大小，提高查询效率
     */
    long long m_raft_state_size;
};

} // namespace raftCore

#endif // RAFT_CORE_PERSISTER_H